#include "server_func.h"

void * (*type_to_func[4])(task_t *)= {cmd,user_register,user_login,transfor};
//接收新的客户端连接并加入监听队列、任务队列
int new_connect(int listenfd,struct epoll_event * events,threadpool_t * threadpool){
    //接收新连接
    struct sockaddr clientaddr;
    socklen_t len;
    int clientfd = accept(listenfd,NULL,NULL);
    if(-1 == clientfd)
        error_log("server_func.c:new_connect::accept");
    int ret = getsockname(clientfd,&clientaddr,&len);
    if(-1 == ret)
        error_log("server_func.c:new_connect::getsockname");
    struct sockaddr_in * addr = (struct sockaddr_in *)&clientaddr;
    client_log(inet_ntoa(addr->sin_addr),"new client connected.");
    //加入监听队列
    //检查监听队列是否已满
    int i;
    for(i = 0; i < EPOLL_EVENT_SIZE; i++){
        if(events[i].data.fd == 0)
            break;
    }
    if(EPOLL_EVENT_SIZE == i){
        error_log("new_connect: events is full.");
        return -1;
    }
    epoll_add_fd(clientfd);
    return clientfd;
}
//接收到退出信号，停止建立新连接、清空任务队列、关闭线程池
void child_exit(int listenfd,threadpool_t * threadpool){
    //将listenfd移出监听队列
    epoll_del_fd(listenfd);
    //清空任务队列、关闭子线程、关闭线程池
    tq_setexit(threadpool->queue);
    for(int i =0; i < THREAD_POOL_SIZE; i++)
        pthread_join(threadpool->threads[i],NULL);
    tp_destroy(threadpool);
    syslog(0,"child_exit");
}
//接收旧文件描述符，创建任务,注意接收到之后将fd从epoll中移除，子线程执行完毕后再将其移入
void make_task(int taskfd,threadpool_t * threadpool){
    train * tra = recv_t(taskfd);
    epoll_del_fd(taskfd);
    task_t * task = (task_t *)calloc(1,sizeof(task_t));
    task->peerfd = taskfd;
    task->funcname = type_to_func[tra->type];
    task->argument = tra->data;
    task->next = NULL;
    tq_enqueue(threadpool->queue,task);
}

//用户注册
void * user_register(task_t * task){
    char * username = task->argument;
    //查找用户名是否已存在
    if(1 == query_username(username)){
        train * t = train_init();
        exit_error(task->peerfd,MSG_NAME_REP);
        return ;
    }
    //发送salt
    char * s = salt();
    send_t(task->peerfd,REGISTER,s);
    //接收密文
    train * t = recv_t(task->peerfd);
    if(REGISTER != t->type){
        error_log("user_register::recv_t::密文接收错误");
        exit_error(task->peerfd,MSG_UNKNOW_ERR);
        return ;
    }
    //在数据库中注册
    if(1 != db_user_reg(username,s,(char *)t->data)){
        error_log("user_register::db_user_reg");
        exit_error(task->peerfd,MSG_REGISTER_ERR);
    }
    //返回成功信号
    send_t(task->peerfd,REGISTER,MSG_REGISTER_SCS);
}
//用户登录
void * user_login(task_t * task){

}
//cmd 
void * cmd(task_t * task){

}
//传输数据
void * transfor(task_t * task){

}